package meterMonitor.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class App {

    // 查询设备信息
    private static final byte[] QUERY_DEVICE = {0x00, 0x03, 0x7F, (byte) 0xF8, 0x00, 0x01, 0x1D, (byte) 0xFE};

    // IP地址
    private static final String HOST = "192.168.1.145";

    // 端口号
    private static final int PORT = 8899;

    // 超时时间
    private static final int TIMEOUT = 5000;

    // 设备地址,可更改
    private static final byte DEV_ADDR = 0x01;

    // 功能码
    private static final byte FUN_CODE = 0x03;

    // 寄存器地址
    private static final byte[] REGISTER = {0x00, 0x00};

    // 查询当前值的命令
    private static final byte[] CURR_VAL = {0x00, 0x08};  // 寄存器地址 Base+0 ~ Base+7(共8位)

    // 查询小时冻结数据
    private static final byte[] HIS_HOUR_VAL = {0x00, 0x08};  // 寄存器地址 Base+8 ~ Base+1010

    // 查询日冻结数据
    private static final byte[] HIS_DAY_VAL = {0x00, 0x08};  // 寄存器地址 Base+1016 ~ Base+1196

    // 查询月冻结数据
    private static final byte[] HIS_MONTH_VAL = {0x00, 0x08};  // 寄存器地址 Base+1202 ~ Base+1304


    public static void checkDeviceStatus() {

        List<String> deviceList = new ArrayList<>();

        deviceList.add("01");
        deviceList.add("02");


        // 广播所有设备

        // 1 从设备信息表中读取所有设备

        // 2 发送命令确定可以通信，则设备正常在线
    }


    public static void main(String[] args) throws Exception {
        // 查询设备信息的命令
        byte[] query = new byte[]{0x00, 0x03, 0x7F, (byte) 0xF8, 0x00, 0x01, 0x1D, (byte) 0xFE};

        // 查询到地址后进行保存，并查询数据
        Socket socket = new Socket();
        try {
            //创建Socket对象，连接服务器
            socket.connect(new InetSocketAddress("192.168.1.145", 8899), 5000);
            //通过客户端的套接字对象Socket方法，获取字节输出流，将数据写向服务器
            OutputStream out = socket.getOutputStream();

            byte[] bytes = new byte[]{0x00, 0x03, 0x02, 0x00, 0x00, 0x08, 0x45, 0x65};

            System.out.println("发送数据:" + bytesToHexString(bytes));

            out.write(bytes);
            out.flush();
            Thread.sleep(300);

            //读取服务器发回的数据，使用socket套接字对象中的字节输入流
            InputStream in = socket.getInputStream();
            byte[] data = new byte[64];
            int len = in.read(data);

            System.out.println("接收的数据长度:" + len);


            // String s = bytesToHexString(bytes);

            System.out.println(bytesToHexString(data));

            for (int i = 0; i < len; i++) {
                System.out.print(Integer.toHexString(data[i]) + " ");
            }
            out.close();
            in.close();
        } catch (IOException e) {
            e.printStackTrace();

        } finally {
            socket.close();
        }


    }


    /**
     * 字节数组转十六进制字符串
     *
     * @param bytes
     * @return
     */
    public static String bytesToHexString(byte[] bytes) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (bytes == null || bytes.length <= 0) {
            return null;
        }
        for (int i = 0; i < bytes.length; i++) {
            int v = bytes[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }


    //
    //
    // public static void main(String[] args) throws Exception {
    //     //一个Scoket代表一路连接
    //     Socket sock = new Socket();
    //     //连接至服务器
    //     sock.connect(new InetSocketAddress("192.168.1.145", 8899));
    //     //InputStream用于接收数据，OutputStreet用于发送数据
    //     InputStream inputStream = sock.getInputStream();
    //     OutputStream outputStream = sock.getOutputStream();
    //
    //     //发送数据
    //     // String outputMsg = "Hello";
    //     byte[] outputData = new byte[]{0x00, 0x03, 0x02, 0x00, 0x00, 0x08, 0x45, 0x65};
    //
    //     // byte[] outputData = outputMsg.getBytes("UTF-8");
    //     outputStream.write(outputData);
    //     // System.out.println(">>" + outputMsg);
    //
    //
    //     System.out.println("_____________");
    //
    //     //接收数据
    //     byte[] inputData = new byte[4000];
    //     int n = inputStream.read(inputData);
    //     String inputMsg = new String(inputData, 0, n, "UTF-8");
    //     System.out.println("<<" + inputMsg);
    //
    //     Thread.sleep(10000);
    //
    //
    //     //关闭连接
    //     // sock.close();
    //
    //
    // }

    /**
     * 网关状态 每次请求数据之前查询网关状态，更新网关在线状态
     *
     * @param bytes
     * @return
     */


    public static byte[] calcCRC(byte[] bytes) {
        byte[] result = new byte[bytes.length + 2];
        for (int i = 0; i < bytes.length; i++) {
            result[i] = bytes[i];
        }
        String crc = getCRC(bytes);
        int low = Integer.parseInt(crc.substring(0, 2), 16);
        int high = Integer.parseInt(crc.substring(2, 4), 16);

        result[bytes.length] = (byte) high;
        result[bytes.length + 1] = (byte) low;
        return result;
    }


    /**
     * CRC 校验
     *
     * @param bytes
     * @return
     */
    public static String getCRC(byte[] bytes) {
        int CRC = 0x0000ffff;
        int POLYNOMIAL = 0x0000a001;

        int i, j;
        for (i = 0; i < bytes.length; i++) {
            CRC ^= ((int) bytes[i] & 0x000000ff);
            for (j = 0; j < 8; j++) {
                if ((CRC & 0x00000001) != 0) {
                    CRC >>= 1;
                    CRC ^= POLYNOMIAL;
                } else {
                    CRC >>= 1;
                }
            }
        }
        return Integer.toHexString(CRC);
    }
}
